今天沒什麼特別要講解的,就是把昨天分配到的部份實作出來吧~
設計部份,登入的主視覺還沒有完全決定,
但用色的主題會以藍色系漸層為基底。
會有一種科技感?
按鈕會以黃、白、黑做設計。
登入頁目前一定會有的設計:
1.浮動的元素
2.主題名稱
3.進入按鈕
主頁面會有的設計:
所以今天就是把有的東西都寫進程式裡,
另外,在遊戲畫面裡,我會想加一點觸碰特效。
好的,那我們就,開始囉~
這是因為實際使用後發現,多頁面的訪問及畫面的建置,
還是使用MaterialApp作為框架最為快速與方便。
而且這也能使開發進程加快許多,因為與平時在使用Flutter開發時的習慣相同。
在需要動態、特效與遊戲本體時,再用Flame的元件來實作。
Future<void> main() async {
///連結硬體
WidgetsFlutterBinding.ensureInitialized();
///設為全螢幕
Flame.device.fullScreen();
///設為垂直
Flame.device.setPortrait();
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
title: '30 days Achieve',
theme: ThemeData(),
home:const LoginPage()));
}
Flame的各種Component,
最後能全部加入到FlameGame中,
也就是遊戲的畫面裡,
而FlameGame能傳入GameWidget裡,
變成Widget。
所以只要把做好的遊戲畫面裝入GameWidget裡,
就能把他放回到平時在開發Flutter時常用的各種容器中啦~
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Stack(
children: [
GameWidget(game: MyGame())
],
),
);
}
}
使用一個叫particles_flutter的套件,就可以做到很神奇的效果。
因為要用在背景,所以會放在Stack容器中,讓他填滿整個背景。
可以透過調整他的數量、速度、動畫、狀態、隨機產生大小及顏色的參數,
客製出你想要的效果…不過整個套件就只有做這件事。
Stack(
children: [
CircularParticle(
onTapAnimation: false,
numberOfParticles: 200,
speedOfParticles: -1,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
maxParticleSize: 1,
isRandSize: true,
isRandomColor: true,
randColorList: const [Colors.white],
awayAnimationCurve: Curves.easeInCubic,
connectDots: false,
),
],
),
官方文件裡就有範例。
做法其實只是在背景放個可偵測TapEvent的PositionComponent,
然後size放到你想要的大小,接著在偵測到手勢的onTapDown裡,
放入想出現的Component,
就可以實現這個效果了。
class TapTarget extends PositionComponent with TapCallbacks{
TapTarget() : super(anchor: Anchor.center);
///背景色
final _paint = Paint()..color = const Color(0x448BA8FF);
///控制被加入的子元素(Component)的列表
final Map<int, Spark> _circles = {};
@override
void onGameResize(Vector2 canvasSize) {
super.onGameResize(canvasSize);
size = canvasSize;
if (size.x < 100 || size.y < 100) {
size = canvasSize;
}
position = canvasSize / 2;
}
@override
void render(Canvas canvas) {
canvas.drawRect(size.toRect(), _paint);
}
@override
void onTapDown(TapDownEvent event) {
final circle = Spark(event.localPosition);
_circles[event.pointerId] = circle;
add(circle);
}
@override
void onLongTapDown(TapDownEvent event) {
_circles[event.pointerId]!.accent();
}
@override
void onTapUp(TapUpEvent event) {
_circles.remove(event.pointerId)!.release();
}
@override
void onTapCancel(TapCancelEvent event) {
_circles.remove(event.pointerId)!.cancel();
}
}
註:Spark是我自定義的Component,若直接複製後,不能運行是正常的。
使用Flame裡的Particles做出來的效果,
可以像加入Component那樣加到其他的Component中。
///建立Particle
CircleParticle circleParticle = CircleParticle(
radius: 1,
paint: Paint()..color = Colors.white,
);
Particle particle = Particle.generate(
count: 10,
lifespan: 1,
generator: (i) =>
AcceleratedParticle(
child: circleParticle,
acceleration: randomVector(),
speed: randomVector(),
position: position),
);
///建立Particle Component
final ParticleSystemComponent psc =
ParticleSystemComponent(particle: particle);
///加到畫面
add(psc);
參考
怎樣用動態的界面讓flutter app變得更生動有趣
Flutter Particles官方文件
Flutter&Flame游戏 - 拾陆】粒子系统 | 粒子的种类
Particles官方文件
Tap events官方文件